<template>
  <view class="uni-container">
    <view class="uni-countDown"
      >下一次刷新时间：<span :style="{ color: countDownColor }">{{
        countDown
      }}</span></view
    >
    <view class="uni-list" v-if="accountList.length > 0">
      <view
        class="uni-list-item"
        v-for="(account, index) in accountList"
        :key="index"
        @longpress="handleLongPress(account, index)"
        @longtap="handleLongPress(account, index)"
      >
        <view class="uni-list-item__header">
          <image
            style="width: 100%; height: 100%; border-radius: 20rpx"
            mode="scaleToFill"
            :src="cardImage"
          >
          </image>
        </view>
        <view class="uni-list-item__content">{{ account.name }}</view>
        <view
          class="uni-list-item__extra"
          @click="handleCopy(switchSecret(account.secret))"
          @tab="handleCopy(switchSecret(account.secret))"
        >
          {{ switchSecret(account.secret) }}
        </view>
      </view>
    </view>
    <view class="uni-list__none" v-else>
      <text>这里空空如也，快去添加账号吧</text>
    </view>

    <!-- 添加账号 -->
    <uni-popup ref="addDialog" type="dialog" :mask-click="false">
      <view class="uni-popup__form">
        <view class="uni-popup__title">添加账号</view>
        <uni-forms ref="form" :modelValue="form" :rules="rules">
          <view class="input-item">
            <input
              class="input-field"
              type="text"
              v-model="form.name"
              placeholder="请输入账号"
            />
          </view>
          <view class="input-item">
            <input
              class="input-field"
              type="text"
              v-model="form.secret"
              placeholder="请输入密匙"
              :disabled="!isMunaul"
            />
          </view>
        </uni-forms>
        <view class="uni-popup__button">
          <button class="mini-btn cancel-btn" @click="handleAddDialogCancel">
            取消
          </button>
          <button class="mini-btn confirm-btn" @click="handleAddDialogConfirm">
            确定
          </button>
        </view>
      </view>
    </uni-popup>

    <!-- 删除提示 -->
    <uni-popup ref="alertDialog" type="dialog" :mask-click="false">
      <uni-popup-dialog
        type="info"
        cancelText="取消"
        confirmText="确定"
        title="提示"
        :content="`确认删除账号${currentAccount.name}吗？`"
        @confirm="dialogAlertConfirm"
      ></uni-popup-dialog>
    </uni-popup>

    <view class="uni-scan__button">
      <button class="default btn cancel-btn" @click="handleImport">
        手动添加
      </button>
      <button class="default btn confirm-btn" @click="handleScan">
        扫码添加
      </button>
    </view>
  </view>
</template>

<script>
const { StorageService, KeyUtilities } = require("@/utils/gauth.js");
const { jsSHA } = require("@/utils/jssha-1.31.min.js");
const storage = StorageService();
import cardImage from "@/static/card.png";
export default {
  data() {
    return {
      cardImage,
      form: {
        name: "",
        secret: "",
      },
      rules: {
        // 对name字段进行必填验证
        name: {
          rules: [
            {
              required: true,
              errorMessage: "请输入账号",
            },
          ],
        },
        // 对email字段进行必填验证
        secret: {
          rules: [
            {
              required: true,
              errorMessage: "请输入密匙",
            },
          ],
        },
      },
      accountList: [],
      countDown: "...",
      deleteIndex: 0,
      currentAccount: {},
      isMunaul: false, //区分是手动添加还是扫码添加
      countDownColor: "black", // 倒计时颜色
    };
  },
  methods: {
    handleCopy(data) {
      uni.setClipboardData({
        data,
        success: function () {
          uni.showToast({
            title: "复制成功",
          });
        },
      });
    },
    // 打开添加账户对话框
    inputDialogToggle() {
      this.$refs.inputDialog.open();
    },
    // 打开确认删除对话框
    alertDialogToggle(account, index) {
      this.deleteIndex = index;
      this.currentAccount = account;
      this.$refs.alertDialog.open();
    },
    dialogAlertConfirm() {
      this.deleteAccount(this.deleteIndex);
    },
    // 添加账户到本地
    addAccount(name, secret) {
      if (!secret) return false;
      const account = {
        name,
        secret,
      };
      let accounts = storage.getItem("accounts");
      if (!accounts) {
        accounts = [];
      }
      accounts.push(account);
      storage.setItem("accounts", accounts);
      this.clearAccount();
      this.updateKeys();
    },
    // 清空表单信息
    clearAccount() {
      this.form.name = "";
      this.form.secret = "";
    },
    // 移除账户
    deleteAccount(index) {
      var accounts = storage.getItem("accounts");
      accounts.splice(index, 1);
      storage.setItem("accounts", accounts);
      this.updateKeys();
    },
    // 更新密钥
    updateKeys() {
      const accounts = storage.getItem("accounts");
      this.accountList = accounts;
    },
    // 转换密钥
    switchSecret(secret) {
      return KeyUtilities(jsSHA).generate(secret);
    },
    // 初始化
    init() {
      const keyUtilities = KeyUtilities(jsSHA);
      let editingEnabled = false;

      if (!storage.getItem("accounts")) {
        storage.setItem("accounts", []);
      }
      this.accountList = storage.getItem("accounts");
      this.updateKeys();
      setInterval(this.timerTick, 1000);
    },
    // 刷新时间计算
    timerTick() {
      var epoch = Math.round(new Date().getTime() / 1000.0);
      var countDown = 30 - (epoch % 30);
      if (epoch % 30 === 0) {
        this.updateKeys();
      }
      this.countDown = countDown < 10 ? `0${countDown}` : countDown;
      this.countDownColor = countDown <= 5 ? "red" : "black";
    },
    // 扫描二维码
    handleScan() {
      const self = this;
      self.isMunaul = false;
      uni.scanCode({
        success: function (res) {
          // 截取secret 如果扫出来的字符串包含totp
          if (res.result.indexOf("totp") > -1) {
            const result = res.result.split("=");
            self.form.secret = result[1];
            self.$refs.addDialog.open();
          } else {
            uni.showToast({
              title: "非TOTP二维码,请更换验证码后重试",
              icon: "none",
              duration: 1000,
            });
          }
        },
        fail: function (error) {},
      });
    },
    // 手动添加
    handleImport() {
      this.clearAccount();
      this.isMunaul = true;
      this.$refs.addDialog.open();
    },
    handleAddDialogCancel() {
      this.$refs.addDialog.close();
    },
    handleAddDialogConfirm() {
      this.$refs.form
        .validate()
        .then((res) => {
          this.form.secret = this.form.secret.replace(/ /g, "");
          this.addAccount(this.form.name, this.form.secret);
          this.$refs.addDialog.close();
        })
        .catch((err) => {
          console.log("表单错误信息：", err);
        });
    },
    handleLongPress(account, index) {
      // 显示操作菜单
      uni.showActionSheet({
        itemList: ["复制密钥", "删除账号"],
        success: (res) => {
          switch (res.tapIndex) {
            case 0: // 复制密钥
              this.handleCopy(account.secret);
              break;
            case 1: // 删除账号
              this.alertDialogToggle(account, index);
              break;
          }
        },
      });
    },
  },
  mounted() {
    this.init();
  },
};
</script>

<style lang="scss">
body,
.uni-container {
  font-family: "Helvetica Neue", Arial, sans-serif;
  background-color: #f5f7fa;
  color: #333;
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.confirm-btn {
  background: linear-gradient(135deg, #4facfe, #007aff);
  color: #ffffff;
  border: none !important;
  box-sizing: border-box;
}

.cancel-btn {
  background: #ffffff;
  color: #007aff;
  border: 1px solid #4facfe !important;
  box-sizing: border-box;
}

.uni-countDown {
  height: 80rpx;
  line-height: 80rpx;
  text-align: right;
  padding: 0 40rpx;
  font-weight: 800;
  background: #ffffff;
  color: #2c3e50;
  border-bottom: 2rpx solid #edf2f7;
  box-sizing: border-box;
}

.uni-list {
  flex: 1;
  overflow: auto;
  padding: 20rpx;

  &::-webkit-scrollbar {
    display: none;
  }

  &-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    background: #fff;
    border: none;
    box-sizing: border-box;
    padding: 20rpx;
    margin: 15rpx 0;
    border-radius: 12rpx;
    box-shadow: 0 2px 8px rgba(79, 172, 254, 0.1);

    &__header {
      width: 120rpx;
      height: 120rpx;
    }

    &__content {
      flex: 1;
      padding: 0 20rpx;
      font-size: 32rpx;
      color: #2c3e50;
      font-weight: 500;
    }

    &__extra {
      color: #007aff;
      font-weight: 600;
      font-size: 36rpx;
      font-family: monospace;
    }
  }
}

.uni-list__none {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  font-size: 28rpx;
}

.uni-scan__button {
  width: 100%;
  height: 140rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border-top: 2rpx solid #edf2f7;
  box-sizing: border-box;
  padding: 0 30rpx;
  gap: 20rpx;

  .btn {
    flex: 1;
    height: 80rpx;
    line-height: 80rpx;
    border: none;
    font-size: 28rpx;
    border-radius: 8rpx;
  }
}

.uni-popup__form {
  width: 600rpx;
  background-color: #fff;
  padding: 40rpx;
}

.uni-popup__title {
  font-size: 36rpx;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 40rpx;
  text-align: center;
}

.input-item {
  display: flex;
  align-items: center;
  padding: 20rpx 0;
  border-bottom: 2rpx solid #edf2f7;
  margin-bottom: 20rpx;

  .input-field {
    flex: 1;
    margin-left: 20rpx;
    height: 60rpx;
    font-size: 28rpx;
    color: #2c3e50;

    &::placeholder {
      color: #94a3b8;
    }
  }
}

.uni-popup__button {
  margin-top: 40rpx;
  display: flex;
  justify-content: flex-end;
  gap: 20rpx;

  .mini-btn {
    min-width: 160rpx;
    height: 70rpx;
    line-height: 70rpx;
    font-size: 28rpx;
    padding: 0 30rpx;
  }

  .confirm-btn {
    background: linear-gradient(135deg, #4facfe, #007aff);
    color: #ffffff;
    border: none;
  }

  .cancel-btn {
    background: #ffffff;
    color: #007aff;
    border: 1px solid #4facfe;
  }
}

// 首先在项目中引入字体图标（这里使用的是示例，你需要自己添加字体图标文件）
@font-face {
  font-family: "iconfont";
  src: url("//at.alicdn.com/t/font_2878668_urm9jbxc8.woff2?t=1634087269221")
    format("woff2");
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 40rpx;
  font-style: normal;
  color: #94a3b8;
}

.icon-user:before {
  content: "\e7ae";
}

.icon-key:before {
  content: "\e7af";
}
</style>
